#!/usr/bin/python
#-*- coding: utf-8 -*-

import sys
reload(sys)
sys.setdefaultencoding('utf8')

import psutil
import platform
import socket
import time

import json

try:
    import requests
except ImportError:
    print 'no requests modules,please you run #pip install requests'
except Exception as e:
    raise e


class Monitor(object):
    #cpu info
    def get_cpu_info(self):
        result = {
            'cpu_count' : psutil.cpu_count(logical=False),
            'cpu_logical_count' : psutil.cpu_count(),
            'cpu_percent' : psutil.cpu_percent(interval=3),
            'cpu_idle_time_percent':psutil.cpu_times_percent().idle
        }
        return result

    #mem info
    def get_mem_info(self):
        vm = psutil.virtual_memory()
        swap = psutil.swap_memory()
        vm_percent = int((1 - vm.free / float(vm.total)) * 100)
        result = {
            'virtual_memory':{
                'vm_total': vm.total/1024/1024/1024,
                'vm_free': vm.free/1024/1024/1024,
                'vm_percent' : vm_percent
            }
        }

        if swap.total: #no swap
            swap_percent = int((1 - swap.free / float(swap.total)) * 100)
            result['swap'] = {
                    'swap_total' : swap.total/1024/1024/1024,
                    'swap_free' : swap.free/1024/1024/1024,
                    'swap_percent' : swap_percent
            }

        return result

    #disk info
    def get_disk_info(self):
        result = {}
        #sdiskusage(total=3000066109440L, used=159102951424L, free=2840963158016L, percent=5.3)
        for _,mountpoint,_,drvice_type in psutil.disk_partitions(all=False):
            if drvice_type == 'cdrom':
                continue
            info = psutil.disk_usage(mountpoint)
            result[mountpoint] =  {
                'total' : info.total,
                'used' : info.used,
                'free' : info.free,
                'percent' : info.percent
            }
        return result

    #disk io
    def get_disk_io(self):
        result = {}
        #read_count=12926, write_count=684106, read_bytes=637838336, write_bytes=6535847936, read_time=34294,
        #write_time=13388797, read_merged_count=1753, write_merged_count=909483, busy_time=6468390
        info = psutil.disk_io_counters(perdisk=True)
        system = self.get_system()
        if system == 'Linux':
            for disk in info:
                try:
                    result[disk] = {
                    'read_merged_count' : info[disk].read_merged_count,
                    'write_merged_count' : info[disk].write_merged_count,
                    'busy_time' : info[disk].busy_time
                    }
                except Exception as e:
                    pass

        for disk in info:
            #windows Linux format
            #read_count=2125, write_count=9348, read_bytes=40928256L, write_bytes=3062726656L, read_time=5248180L, write_time=5068674L
            result[disk] = {
                'read_count' : info[disk].read_count,
                'write_count' : info[disk].write_count,
                'read_bytes' : info[disk].read_bytes,
                'write_bytes' : info[disk].write_bytes,
                'read_time' : info[disk].read_time,
                'write_time' : info[disk].write_time,
            }
        return result

    #system
    def get_system(self):
        return platform.system()

    #users
    def get_users(self):
        users = psutil.users()
        result = {'count' : len(users),}
        return result

    #pids
    def get_pids(self):
        pids = psutil.pids()
        result = { 'count' : len(pids)}
        return result

    #network info
    def get_network_info(self):
        result = {}
        network_info = psutil.net_if_addrs()
        network_ios = psutil.net_io_counters(pernic=True)
        system = self.get_system()
        if system == 'Linux' :
            result['network_info'] = {}
            for info in network_info:
                result['network_info'][info] = {
                    'ipaddress' : network_info[info][0].address,
                    'netmask' : network_info[info][0].netmask,
                    'broadcast' : network_info[info][0].broadcast,
                }
            result['ips'] = dict([(nic,network_info[nic][0][1]) for nic in network_info if nic != 'lo'])

        result['network_ios'] = {}
        for nic in network_ios:
            #bytes_sent=0L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0L
            try:
                if '{' in nic:
                    continue
                nic.encode('utf8')
            except Exception as e:
                continue
            result['network_ios'][nic] = {
                'bytes_sent' : network_ios[nic].bytes_sent,
                'bytes_recv' : network_ios[nic].bytes_recv,
                'packets_sent' : network_ios[nic].packets_sent,
                'packets_recv' : network_ios[nic].packets_recv,
                'errin' : network_ios[nic].errin,
                'errout' : network_ios[nic].errout,
                'dropin' : network_ios[nic].dropin,
                'dropout' : network_ios[nic].dropout,
            }
        result['conn_count'] = len(psutil.net_connections())
        return result

    #all
    def get_all_info(self):
        result = {
            'mems' : self.get_mem_info(),
            'cpus' : self.get_cpu_info(),
            'disks' : {'disks' : self.get_disk_info(),'disk_ios' : self.get_disk_io()},
            'networks' : self.get_network_info(),
            'users' : self.get_users(),
            'pids' : self.get_pids(),
            'system' : self.get_system(),
        }
        return result

if __name__ == '__main__':
    m = Monitor()
    #print m.get_all_info()
    data =  m.get_all_info()
    hostname = socket.gethostname()
    timestamp = time.time()
    data['hostname'] = hostname
    data['timestamp']  = timestamp
    data = json.dumps(data)
    try:
        r = requests.post('http://192.168.0.153:9001/apis/monitor',data={'data':data})
        print r.text
    except Exception as e:
        raise e
